﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using RibbonEditor;
using RibbonEditor.Templates;
using RibbonEditor.LocLabels;
using RibbonEditor.AppCode;

namespace RibbonEditor
{
    class RibbonDiffXml : IXmlBuildable
    {
        public CustomActions CustomActions { get; set; }
        public _Global.Templates Templates { get; set; }
        public CommandDefinitions CommandDefinitions { get; set; }
        public RuleDefinitions RuleDefinitions { get; set; }
        public _Global.LocLabels LocLabels { get; set; }
        public bool RibbonNotSupported { get; set; }
        
        public RibbonDiffXml(XmlNode ribbonNode)
        {
            try
            {
                if (ribbonNode.SelectSingleNode("CustomActions") != null)
                {
                    this.CustomActions = new CustomActions(ribbonNode.SelectSingleNode("CustomActions"));
                }

                if (ribbonNode.SelectSingleNode("Templates") != null)
                {
                    this.Templates = new _Global.Templates(ribbonNode.SelectSingleNode("Templates"));
                }

                if (ribbonNode.SelectSingleNode("CommandDefinitions") != null)
                {
                    this.CommandDefinitions = new CommandDefinitions(ribbonNode.SelectSingleNode("CommandDefinitions"));
                }

                if (ribbonNode.SelectSingleNode("RuleDefinitions") != null)
                {
                    this.RuleDefinitions = new RuleDefinitions(ribbonNode.SelectSingleNode("RuleDefinitions"));
                }

                if (ribbonNode.SelectSingleNode("LocLabels") != null)
                {
                    this.LocLabels = new _Global.LocLabels(ribbonNode.SelectSingleNode("LocLabels"));
                }

                if (ribbonNode.SelectSingleNode("RibbonNotSupported") != null)
                {
                    this.RibbonNotSupported = true;
                }
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Obtain the Xml document representing a ribbon
        /// </summary>
        /// <returns></returns>
        public XmlDocument GetRibbonDiffXmlDocument()
        {
            XmlDocument ribbonDiffXmlDocument = new XmlDocument();
            ribbonDiffXmlDocument.LoadXml("<RibbonDiffXml></RibbonDiffXml>");

            try
            {
                this.AddCustomActionsNode(ribbonDiffXmlDocument);
                this.AddTemplatesNode(ribbonDiffXmlDocument);
                this.AddCommandDefinitionsNode(ribbonDiffXmlDocument);
                this.AddRuleDefinitionsNode(ribbonDiffXmlDocument);
                this.AddLocLabelsNode(ribbonDiffXmlDocument);

                if (this.RibbonNotSupported)
                {
                    XmlNode ribbonNotSupportedNode = ribbonDiffXmlDocument.CreateElement("RibbonNotSupported");
                    ribbonDiffXmlDocument.DocumentElement.AppendChild(ribbonDiffXmlDocument);
                }

            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return ribbonDiffXmlDocument;
        }

        private void AddCustomActionsNode(XmlDocument ribbonDiffXmlDocument)
        {
            if (this.CustomActions != null)
            {
                this.CustomActions.AddNode(ribbonDiffXmlDocument);
            }
        }

        private void AddTemplatesNode(XmlDocument ribbonDiffXmlDocument)
        {
            if (this.Templates != null)
            {
                this.Templates.AddNode(ribbonDiffXmlDocument);
            }
        }

        private void AddCommandDefinitionsNode(XmlDocument ribbonDiffXmlDocument)
        {
            this.CommandDefinitions.AddNode(ribbonDiffXmlDocument);
        }

        private void AddRuleDefinitionsNode(XmlDocument ribbonDiffXmlDocument)
        {
            if (this.RuleDefinitions != null)
            {
                this.RuleDefinitions.AddNode(ribbonDiffXmlDocument.DocumentElement);
            }
        }

        private void AddLocLabelsNode(XmlDocument ribbonDiffXmlDocument)
        {
            if (this.LocLabels != null)
            {
                this.LocLabels.AddNode(ribbonDiffXmlDocument);
            }
        }

        public void BuildTreeViewElement(TreeNode parentNode)
        {
            try
            {
                parentNode.ContextMenuStrip = ContextMenuStripHelper.BuildStandardContextMenuStrip(parentNode);

                if (this.CustomActions != null)
                {
                    this.CustomActions.BuildTreeViewElement(parentNode);
                }

                if (this.Templates != null)
                {
                    this.Templates.BuildTreeViewElement(parentNode);
                }

                if (this.CommandDefinitions != null)
                {
                    this.CommandDefinitions.BuildTreeViewElement(parentNode);
                }

                if (this.RuleDefinitions != null)
                {
                    this.RuleDefinitions.BuildTreeViewElement(parentNode);
                }

                if (this.LocLabels != null)
                {
                    this.LocLabels.BuildTreeViewElement(parentNode);
                }

                if (this.RibbonNotSupported)
                {
                    TreeNode notSupportedNode = new TreeNode("RibbonNotSupported");
                    parentNode.Nodes.Add(notSupportedNode);
                }
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #region IXmlBuildable Members

        public void AddNode(XmlNode parentNode)
        {
            try
            {
                XmlNode node = GetRibbonDiffXmlDocument().DocumentElement;
                XmlNode importNode = parentNode.OwnerDocument.ImportNode(node, true);
                parentNode.AppendChild(importNode);
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion
    }
}
